/*
package com.hsz.control.aspect;

import com.hsz.base.interactive.redis.RedisClusterUtils;
import com.hsz.base.interactive.redis.bean.RedisLock;
import com.hsz.base.interactive.redis.bean.TryLock;
import com.hsz.base.standard.constant.InnerError;
import com.hsz.base.util.BeanUtil;
import com.hsz.base.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.IntStream;

*/
/**
 * Lock aspect
 *
 * @description: 上锁
 * @author: cyj
 * @date 2020 -11-17 09:38:36
 *//*

@Aspect
@Component
@Order(2)
@Slf4j
public class LockAspect {

    */
/**
     * Redis cluster utils
     *//*

    @Autowired
    private RedisClusterUtils redisClusterUtils;

    */
/**
     * Try lock aspect
     *//*

    @Pointcut(value = "@annotation(com.hsz.base.interactive.redis.bean.TryLock)")
    public void tryLockAspect() {
    }

    */
/**
     * Try catch object
     *
     * @param point point
     * @return the object
     *//*

    @Around("tryLockAspect()")
    public Object tryCatch(ProceedingJoinPoint point) {
        Method method = BeanUtil.getMethod(point);
        TryLock tryLock = method.getAnnotation(TryLock.class);
        String key = generalKey(tryLock, point);
        log.info("try lock key -> {}", key);
        RedisLock redisLock = new RedisLock()
                .setKey(key).setValue(System.currentTimeMillis()).setExpire(tryLock.expire());
        try {
            Boolean isLock = false;
            for (int i = 0; i < tryLock.tryCount(); i++) {
                isLock = redisClusterUtils.tryLock(redisLock);
                if (isLock) {
                    break;
                } else {
                    CommonUtil.pause(tryLock.intervalTime());
                }
            }
            if (!isLock) {
                return null;
            }
            return point.proceed();
        } catch (Throwable throwable) {
            log.info(throwable.getMessage());
            return null;
        } finally {
            redisClusterUtils.unLock(redisLock);
        }
    }

    private String generalKey(TryLock tryLock, ProceedingJoinPoint point) {
        String keyTemp = tryLock.key();
        boolean jointKey = tryLock.jointKey();
        if (!jointKey) {
            return keyTemp;
        }
        // 组装比较参数
        // 比较
        Object[] args = point.getArgs();
        String[] paramNames = ((CodeSignature) point.getSignature()).getParameterNames();
        List<String> keysDescription = getKeysDescription(keyTemp, paramNames);
        Map<String, Class> argsClass = new LinkedHashMap<>();
        Map<String, Object> argsObject = new LinkedHashMap<>();
        IntStream.range(0, args.length).forEach(i -> {
            Object tObject = args[i];
            if (null == tObject) {
                return;
            }
            Class tClass = tObject.getClass();
            String paramName = paramNames[i];
            argsClass.put(paramName, tClass);
            argsObject.put(paramName, tObject);
        });
        if (CollectionUtils.isEmpty(argsClass)) {
            throw new RuntimeException(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL);
        }
        // 组装key
        StringBuffer key = new StringBuffer();
        keysDescription.stream().forEach(keyDescription -> {
            List<String> keyTemp2 = Arrays.asList(keyDescription.split("\\."));
            Class tClass = argsClass.get(keyTemp2.get(0).replace("#", ""));
            Object tObejct = argsObject.get(keyTemp2.get(0).replace("#", ""));
            if (1 == keyTemp2.size()) {
                if (null == tObejct) {
                    throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL, keyTemp2));
                }
                key.append(tObejct).append(".");
            } else {
                PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(tClass, keyTemp2.get(1));
                if (null == propertyDescriptor) {
                    throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL, keyTemp2));
                }
                Method readMethod = propertyDescriptor.getReadMethod();
                if (null == readMethod) {
                    throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL, keyTemp2));
                }
                try {
                    Object value = readMethod.invoke(tObejct);
                    if (null == value) {
                        throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL, keyTemp2));
                    }
                    key.append(value).append(".");
                } catch (IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL, keyTemp2));
                }
            }
        });
        key.delete(key.length() - 1, key.length());
        return key.toString();
    }

    private List<String> getKeysDescription(String keyTemp, String[] paramNames) {
        List<String> asList = Arrays.asList(paramNames);
        List<String> tempList = Arrays.asList(keyTemp.split(","));
        if (CollectionUtils.isEmpty(tempList)) {
            throw new RuntimeException(InnerError.TRY_LOCK_JOIN_KEY_IS_NULL);
        }
        // 校验一波
        tempList.parallelStream().forEach(key -> {
            String[] t = key.split("\\.");
            String keyHead = t[0];
            if (!keyHead.startsWith("#") || !asList.contains(keyHead.replace("#", ""))) {
                throw new RuntimeException(String.format(InnerError.TRY_LOCK_JOIN_KEY_FORMAT_ERROR, key));
            }
        });
        return tempList;
    }
}
*/
